package vn.conghuy.talkwithme.responsor.responsor;

import vn.conghuy.talkwithme.R;
import vn.conghuy.talkwithme.data.sqlmodel.WordModel;
import vn.conghuy.talkwithme.utils.IntWrapper;
import vn.conghuy.talkwithme.utils.StringWrapper;
import vn.conghuy.talkwithme.utils.Utils;
import android.content.Context;

//Note : It can't continue because android 2.x cannot set alarm

public class AlarmResponsor extends Responsor{
	
	private static final int RELATIVE_MISS_INFO = 1;
	
	private static final int PARSE_RESULT_OK = 0;
	private static final int PARSE_RESULT_INVALID = 1;
	private static final int PARSE_RESULT_FAIL = 2;
	
	private static final String FOR_KEYWORD = "for";
	private static final String PAST_KEYWORD = "past";
	private static final String TO_KEYWORD = "to";
	private static final String OCLOCK_KEYWORD = "o'clock";
	
	/**
	 * @uml.property  name="wordStop" multiplicity="(0 -1)" dimension="1"
	 */
	String[] wordStop;
	/**
	 * @uml.property  name="cancelPhrases" multiplicity="(0 -1)" dimension="1"
	 */
	String[] cancelPhrases;
	/**
	 * @uml.property  name="alarmVerbs" multiplicity="(0 -1)" dimension="1"
	 */
	String[] alarmVerbs;
	/**
	 * @uml.property  name="alarmKeywords" multiplicity="(0 -1)" dimension="1"
	 */
	String[] alarmKeywords;
	/**
	 * @uml.property  name="alarmInvalid" multiplicity="(0 -1)" dimension="1"
	 */
	String[] alarmInvalid;
	/**
	 * @uml.property  name="alarmMissing" multiplicity="(0 -1)" dimension="1"
	 */
	String[] alarmMissing;
	
	/**
	 * @uml.property  name="timeToSet"
	 * @uml.associationEnd  multiplicity="(1 1)" inverse="this$0:vn.conghuy.talkwithme.responsor.responsor.AlarmResponsor$MyTime"
	 */
	MyTime timeToSet;
	
	public AlarmResponsor(Context context) {
		super(context);
		timeToSet = new MyTime();
		
		wordStop = WordModel.GetWordsByAction("stop");
		cancelPhrases = WordModel.GetWordsByAction("task cancel");
		alarmVerbs = WordModel.GetWordsByAction("alarm verb");
		alarmKeywords = WordModel.GetWordsByAction("alarm keyword");
		alarmInvalid = WordModel.GetWordsByAction("alarm invalid");
		alarmMissing = WordModel.GetWordsByAction("alarm miss");
	}
	
	@Override
	public String response(String request) {
		
		if(Utils.isExistStringInArray(wordStop, request) == true){
			relativeLastResponse = RELATIVE_NONE;
			return Utils.getRandomString(cancelPhrases);
		}
		
		switch (relativeLastResponse) {
		case RELATIVE_NONE:
			
			StringWrapper alarmVerbWrapper = new StringWrapper();
			StringWrapper alarmKeywordWrapper = new StringWrapper();
			
			if(Utils.isExistElemInArrayIsWordOfStr(alarmVerbs, request, alarmVerbWrapper)
					&& Utils.isExistElemInArrayIsWordOfStr(alarmKeywords, request, alarmKeywordWrapper)){
				int alarmIndex = Utils.indexOfWord(request, FOR_KEYWORD);
				
				// exist "for" keyword
				if(alarmIndex != -1){
					alarmIndex += FOR_KEYWORD.length() + 1;
				}
				// not exist "for" keyword
				else{
					alarmIndex = request.indexOf(alarmKeywordWrapper.getStr());
					alarmIndex += alarmKeywordWrapper.getStr().length() + 1;
				}
				
				String alarmPhrase = request.substring(alarmIndex);
				int result = parseAlarmPhrase(alarmPhrase);
				if(result == PARSE_RESULT_OK){
					// TODO : set alarm
					relativeLastResponse = RELATIVE_NONE;
					return context.getString(R.string.alarm_command);
				}
				else{
					relativeLastResponse = RELATIVE_MISS_INFO;
					return Utils.getRandomString(alarmMissing);
				}
			}
			break;

		default:
			break;
		}
		return super.response(request);
	}
	
	int parseAlarmPhrase(String alarmPhrase){
		
		if(alarmPhrase.contains(PAST_KEYWORD)){
			int keywordIndex = Utils.indexOfWord(alarmPhrase, PAST_KEYWORD);
			String minutePhrase = alarmPhrase.substring(0, keywordIndex - 2);
			String hourPhrase = alarmPhrase.substring(keywordIndex + PAST_KEYWORD.length() + 1);
			IntWrapper minuteWrapper = new IntWrapper();
			IntWrapper hourWrapper = new IntWrapper();
			boolean hasMinute = Utils.hasNumber(minutePhrase, minuteWrapper);
			boolean hasHour = Utils.hasNumber(hourPhrase, hourWrapper);
			int hour = hourWrapper.getInt() - 1;
			int minute = 60 - minuteWrapper.getInt();
			if(hasMinute == true && hasHour == true && hour >= 0 && hour < 24 && minute >= 0 && minute < 60){
				timeToSet.set(hour, minute);
				return PARSE_RESULT_OK;
			}
		}
		else if(alarmPhrase.contains(TO_KEYWORD)){
			int keywordIndex = Utils.indexOfWord(alarmPhrase, TO_KEYWORD);
			String minutePhrase = alarmPhrase.substring(0, keywordIndex - 2);
			String hourPhrase = alarmPhrase.substring(keywordIndex + TO_KEYWORD.length() + 1);
			IntWrapper minuteWrapper = new IntWrapper();
			IntWrapper hourWrapper = new IntWrapper();
			boolean hasMinute = Utils.hasNumber(minutePhrase, minuteWrapper);
			boolean hasHour = Utils.hasNumber(hourPhrase, hourWrapper);
			int hour = hourWrapper.getInt() - 1;
			int minute = 60 - minuteWrapper.getInt();
			if(hasMinute == true && hasHour == true && hour >= 0 && hour < 24 && minute >= 0 && minute < 60){
				timeToSet.set(hour, minute);
				return PARSE_RESULT_OK;
			}
			else return PARSE_RESULT_INVALID;
		}
		else if(alarmPhrase.contains(OCLOCK_KEYWORD)){
			int keywordIndex = alarmPhrase.indexOf(PAST_KEYWORD);
			String timePhrase = alarmPhrase.substring(0, keywordIndex - 2);
			IntWrapper timeWrapper = new IntWrapper();
			boolean hasTime = Utils.hasNumber(timePhrase, timeWrapper);
			int time = timeWrapper.getInt();
			if(hasTime == true && time >= 0 && time < 24){
				timeToSet.set(time, 0);
			}
			else return PARSE_RESULT_INVALID;
		}
		return PARSE_RESULT_FAIL;
	}

	@Override
	public int relativeWithLastRequest(String sentence) {
		return relativeLastResponse;
	}
	
	@Override
	public void reset() {
		super.reset();
		timeToSet.isValid = false;
		
	}
	
	/**
	 * @author  Huy
	 */
	class MyTime{
		/**
		 * @uml.property  name="hour"
		 */
		private int hour;
		/**
		 * @uml.property  name="minute"
		 */
		private int minute;
		/**
		 * @uml.property  name="isValid"
		 */
		private boolean isValid;
		
		public MyTime(){
			isValid = false;
		}
		
		public MyTime(int hour, int minute){
			isValid = true;
			this.hour = hour;
			this.minute = minute;
		}
		
		void set(int hour, int minute){
			this.hour = hour;
			this.minute = minute;
			isValid = true;
		}
		
		void reset(){
			isValid = false;
		}

		/**
		 * @return
		 * @uml.property  name="hour"
		 */
		public int getHour() {
			return hour;
		}

		/**
		 * @return
		 * @uml.property  name="minute"
		 */
		public int getMinute() {
			return minute;
		}

		/**
		 * @return
		 * @uml.property  name="isValid"
		 */
		public boolean isValid() {
			return isValid;
		}
	}
}
